package gobelinmaker.data;

import java.util.HashMap;

/**
 * Lyuk alaposzálya.
 *
 * @author imruf84
 */
public class Hole {

    /**
     * Szomszédok oldalainak az azonosítói.
     */
    public static final String TOP = "t";
    public static final String BOTTOM = "b";
    public static final String LEFT = "l";
    public static final String RIGHT = "r";
    public static final String[] sides = {TOP, BOTTOM, LEFT, RIGHT};

    /**
     * Szomszédok.
     */
    private final HashMap<String, Hole> childs = new HashMap<>();
    /**
     * Sorszám.
     */
    private final int row;
    /**
     * Oszlopszám.
     */
    private final int column;
    /**
     * Lyuk színe.
     */
    private HoleColor color = null;

    /**
     * Konstruktor.
     *
     * @param row sorszám
     * @param column oszlopszám
     * @param t felső szomszéd
     * @param b alsó szomszéd
     * @param l bal szomszéd
     * @param r jobb szomszéd
     * @param color szín
     */
    public Hole(int row, int column, Hole t, Hole b, Hole l, Hole r, HoleColor color) {
        this.setChild(t, Hole.TOP, true);
        this.setChild(b, Hole.BOTTOM, true);
        this.setChild(l, Hole.LEFT, true);
        this.setChild(r, Hole.RIGHT, true);
        this.row = row;
        this.column = column;
        this.color = color;
    }

    /**
     * Szomszéd beállítása.
     *
     * @param c lyuk
     * @param side oldal
     * @param setChild igaz esetén a szomszédot is beállítjuk
     */
    private void setChild(Hole c, String side, boolean setChild) {

        this.childs.put(side, c);

        if (!(null == c) && setChild) {
            c.setChild(this, this.getOppositeSide(side), false);
        }
    }

    /**
     * Ellentétes oldal lekérdezése.
     *
     * @param s oldal
     * @return ellentétes oldal
     */
    private String getOppositeSide(String s) {

        if (s.equals(Hole.TOP)) {
            return Hole.BOTTOM;
        }
        if (s.equals(Hole.BOTTOM)) {
            return Hole.TOP;
        }
        if (s.equals(Hole.LEFT)) {
            return Hole.RIGHT;
        }
        if (s.equals(Hole.RIGHT)) {
            return Hole.LEFT;
        }

        return null;
    }

    /**
     * Lyuk eltávolítása a szomszédokból.
     */
    private void remove() {

        // Ha van szomszéd akkor a szomszédból eltávolítjuk a jelenlegit.
        for (String s : Hole.sides) {
            Hole child = this.getChild(s);
            if (!(null == child)) {
                child.setChild(null, s, true);
            }
        }

    }

    /**
     * Lyuk szomszédjának az oldalának a lekérdezése.
     *
     * @param child lyuk
     * @return oldal
     */
    private String getSide(Hole child) {

        for (String s : Hole.sides) {
            if (child == this.getChild(s)) {
                return s;
            }
        }

        return null;
    }

    /**
     * Szomszéd lekérdezése.
     *
     * @param side oldal
     * @return lyuk
     */
    public Hole getChild(String side) {
        return (this.childs.containsKey(side) ? this.childs.get(side) : null);
    }

    /**
     * Felső szomszéd lekérdezése.
     *
     * @return lyuk
     */
    public Hole top() {
        return this.getChild(Hole.TOP);
    }

    /**
     * Alsó szomszéd lekérdezése.
     *
     * @return lyuk
     */
    public Hole bottom() {
        return this.getChild(Hole.BOTTOM);
    }

    /**
     * Bal szomszéd lekérdezése.
     *
     * @return lyuk
     */
    public Hole left() {
        return this.getChild(Hole.LEFT);
    }

    /**
     * Jobb szomszéd lekérdezése.
     *
     * @return lyuk
     */
    public Hole right() {
        return this.getChild(Hole.RIGHT);
    }

    /**
     * Sorszám lekérdezése.
     *
     * @return sorszám
     */
    public int getRow() {
        return this.row;
    }

    /**
     * Oszlopszám lekérdezése.
     *
     * @return oszlopszám
     */
    public int getColumn() {
        return this.column;
    }

    /**
     * Szín megadása.
     *
     * @param color szín
     */
    public void setHoleColor(HoleColor color) {
        this.color = color;
    }

    /**
     * Szín lekérdezése.
     *
     * @return szín
     */
    public HoleColor getHoleColor() {
        return this.color;
    }
}
